#ifndef __MO_LOCAL_SDK_INTERFACE_H
#define __MO_LOCAL_SDK_INTERFACE_H

#include "MoCommon.h"
#include "MoTypes.h"
#include "MoException.h"

#include <stddef.h>

#ifdef __cplusplus

#ifndef IN
#define IN
#endif  // IN

#ifndef OUT
#define OUT
#endif  // OUT

extern "C" {
    #define DLL_API_C_DECL extern "C" __attribute__((visibility("default")))
#endif

DLL_API_C_DECL int moLocalGetSdkVersion(OUT char *const pSdkVer);

DLL_API_C_DECL char *moLocalGetErrorString(IN const int ErrorCode);

//return
//0 -- no need to update
//1 -- need update
//-1 or less -- error
DLL_API_C_DECL int moCheckFirmware(IN const char *patchFilePath);

//return
//0 -- succeed  
//1 -- no need to update
//-1 failed to update, but recovered to old version
//-2 failed to update, nor recover. The firmware may broken!
DLL_API_C_DECL int moUpdateFirmware(IN const char *patchFilePath);

//return 0 - normal mode     1 - compatible mode
DLL_API_C_DECL int moLocalCameraIsInCompatibleMode();

DLL_API_C_DECL int moLocalOpenCamera();
DLL_API_C_DECL int moLocalCloseCamera();

DLL_API_C_DECL int moLocalSuspendCamera();
DLL_API_C_DECL int moLocalResumeCamera();

DLL_API_C_DECL int moLocalGetBaseAndBxf(OUT double* const pBase,OUT double* const pBxF, IN int SensorId = 0);

DLL_API_C_DECL int moLocalGetIMUEnable(OUT bool *const pEnable);
DLL_API_C_DECL int moLocalSetIMUEnable(IN const bool Enable);
DLL_API_C_DECL int moLocalGetIMUData(OUT MoIMUData* const pIMUData, OUT int *pCount);

DLL_API_C_DECL int moLocalGetSensorInfoList(OUT MoSensorData* const pList, OUT int *pSize);
DLL_API_C_DECL int moLocalGetStreamInfoList(OUT MoStreamInfo* const pList, OUT int *pSize, OUT int *const pCurIdx, IN int SensorId = 0);

DLL_API_C_DECL int moLocalGetCurrentStreamIdx(OUT int *const pIdx, IN int SensorId = 0);
DLL_API_C_DECL int moLocalSetCurrentStreamByIdx(IN const int Index, IN int SensorId = 0);

DLL_API_C_DECL int moLocalGetCurrentResolution(OUT int *const pWidth, OUT int *pHeight, IN int SensorID = 0);
DLL_API_C_DECL int moLocalSetCurrentResolution(IN const int Width, IN const int Height, IN int SensorID = 0);

DLL_API_C_DECL int moLocalSetStreamType(IN unsigned int StreamType, IN int SensorId = 0);
DLL_API_C_DECL int moLocalGetStreamType(OUT unsigned int *const pStreamType, IN int SensorId = 0);

DLL_API_C_DECL int moLocalSetSensorDataUploadEnable(IN unsigned char Enable);
DLL_API_C_DECL int moLocalGetSensorDataUploadEnable(OUT unsigned char *const pEnable);

DLL_API_C_DECL int moLocalGetOneRGBFrame(OUT MoFrame *pFrm, int SensorId = -1);
DLL_API_C_DECL int moLocalGetOneRGBDFrame(OUT MoFrame *pFrm, int SensorId = -1);
DLL_API_C_DECL int moLocalDecodeRGBDFrame(IN const MoFrame *const pRGBDFrm, OUT MoFrame *const pDispFrm, OUT MoFrame *const pRefFrm, OUT double *const pBxf = NULL, OUT double *const pBaseLine = NULL);

//need call moReleaseFrame() to free pLeftFrm & pRightFrm
DLL_API_C_DECL int moLocalSplitRGBFrame(IN const MoFrame *const pRGBFrm, OUT MoFrame *const pLeftFrm, OUT MoFrame *const pRightFrm, IN bool IfByHori = true);
DLL_API_C_DECL int moLocalReleaseFrame(IN MoFrame *const pFrame);


DLL_API_C_DECL int moLocalGetFPSRange(OUT unsigned char *const pMaxFPS, OUT unsigned char *pMinFPS, IN int SensorId = 0);
DLL_API_C_DECL int moLocalGetFPS(OUT double *const pFPS, IN int SensorId = 0);
DLL_API_C_DECL int moLocalSetFPS(IN const unsigned char FPS, IN int SensorId = 0);

DLL_API_C_DECL int moLocalSetFillLightType(IN const unsigned char Type);
DLL_API_C_DECL int moLocalGetFillLightType(OUT unsigned char *const pType);

DLL_API_C_DECL int moLocalSetFillLightBrightness(IN const uint8_t Birghtness);
DLL_API_C_DECL int moLocalGetFillLightBrightness(OUT uint8_t *const pBirghtness);

DLL_API_C_DECL int moLocalEnableLineOffsetAdjust(IN int SensorId = 0);
DLL_API_C_DECL int moLocalDisableLineOffsetAdjust(IN int SensorId = 0);
DLL_API_C_DECL int moLocalGetLineOffsetAdjustStatus(OUT bool *pIfFinish, IN int SensorId = 0);

DLL_API_C_DECL int moLocalEnableDispOffsetAdjust(IN int SensorId = 0);
DLL_API_C_DECL int moLocalDisableDispOffsetAdjust(IN int SensorId = 0);
DLL_API_C_DECL int moLocalGetDispOffsetAdjustStatus(OUT bool *pIfFinish, IN int SensorId = 0);

DLL_API_C_DECL int moLocalGetSerialNumber(OUT unsigned char* const pSN, OUT int *pSize);

DLL_API_C_DECL void moLocalRegisterExceptionCallback(IN mo_exception_callback callback_func);

DLL_API_C_DECL int moLocalLoadIntrinsicFromDev(OUT MoFullStereoCameraParams *pIntri);

DLL_API_C_DECL int moLocalGetCameraIntrinsics(OUT MoCameraIntrinsics *pInfo, IN int SensorId = 0);
DLL_API_C_DECL int moLocalGetCameraIntrinsicsFromFrm(IN MoFrame *pFrm, OUT MoCameraIntrinsics *pInfo);

DLL_API_C_DECL int moLocalRemoveDupTexture(OUT MoFrame **ppDispForVSLAM, IN OUT MoFrame *pDisp, IN MoFrame *pRef, 
                    IN float farPlaneInMM, IN uint16_t ROIStartX, IN uint16_t ROIStartY, IN uint16_t ROIWidth, IN uint16_t ROIHeight, 
                    OUT float *ROIDispFillRate = NULL);

DLL_API_C_DECL uint32_t moLocalCheckOcclusion(IN const MoFrame* pDispForVSLAM, IN const MoFrame* ref, IN uint16_t ROIStartX, IN uint16_t ROIStartY, IN uint16_t ROIWidth, IN uint16_t ROIHeight);
DLL_API_C_DECL float moLocalIspLRDiffRate(IN uint32_t rect, IN const MoFrame* ispLeft, IN const MoFrame* ispRight);
DLL_API_C_DECL void moLocalResetOcclusionCheck();

DLL_API_C_DECL int moLocalGetOneFrame(OUT MoFrame *const pFrame);

DLL_API_C_DECL int moLocalGetCameraTemperature(OUT double *pTemperature);

//return log count, each log ideally is one line of the string
DLL_API_C_DECL int moLocalGetSDKLog(OUT char *pBuf, IN int length);

//default value is 100, which is original setting. Less level means darker output. Min level should >=30.
DLL_API_C_DECL int moLocalGetAERangeLevel(uint8_t *pLevel);
DLL_API_C_DECL int moLocalSetAERangeLevel(uint8_t level = 100);

//Get exposure params, brightness 0-255, gain 1-8
//The AE logic is try to stick gain to 1 and lengthen exp time, so when gain > 1 means it is already dark
//The brightness target AE set to 74, let's say if gain > 7 and brightness < 60 is the tresh hold for filllight
//Note: If the camera face a black surface, the gain will increase.
DLL_API_C_DECL int moLocalGetExpParams(OUT float *brightness, OUT float *gain);

//For old camara, version is 100, new camara is 200
DLL_API_C_DECL int moLocalGetCameraCapabilityVersion(OUT int *pVersion);

DLL_API_C_DECL int moLocalGetReferenceCameraParams(OUT MoMonoCameraParams *pParams, OUT double *pBxf, OUT double *pBaseline, OUT int *pResolutionWidth, OUT int *pResolutionHeight);

/**
 * @brief 获取Simor双目内参数据
 *
 * @param pSimorParams
 * @return DLL_API_C_DECL
 */
DLL_API_C_DECL int moLocalGetSimorBinocularParameter(OUT MoBinocularCameraParams *pSimorParams);

/**
 * @brief 获取ISP双目内参数据
 *
 * @param pIspParams
 * @return DLL_API_C_DECL
 */
DLL_API_C_DECL int moLocalGetIspBinocularParameter(OUT MoBinocularCameraParams *pIspParams);

/**
 * @brief
 * 获取ISP矫正参数数据。矫正参数数据为元橡基于一定规则计算和生产建议数据，方便用户直接使用。用户也可以忽略该参数，基于自身特定需求，使用双目基础参数自行计算矫正参数
 *
 * @param pRectifiedIspParams
 * @return DLL_API_C_DECL
 */
DLL_API_C_DECL int moLocalGetRectifyIspBinocularParameter(OUT MoRectifyBinocularParams *pRectifiedIspParams);

typedef uint8_t AEWeight[25];

DLL_API_C_DECL int moLocalSetAEWeight(IN AEWeight weight);

//NOTE: AEWeight is already a pointer, so the pWeight no more need '*pWeight' but 'pWeight'
DLL_API_C_DECL int moLocalGetAEWeight(OUT AEWeight pWeight);

/**
 * @brief
 * 对视差图进行深度过滤，清除重复纹理
 *
 * @param pDisp，视差图数据
 */
DLL_API_C_DECL int moLocalRemoveDupTextureV2(IN OUT MoFrame *pDisp);
//only support 10HZ,20HZ,50HZ,100HZ
DLL_API_C_DECL int moLocalSetMAGFrequencyEnable(IN int frequency);
DLL_API_C_DECL int moLocalGetMagData(OUT MoMAGData* const pMagData, OUT int *pCount);
DLL_API_C_DECL int moLocalGetImuRectifyParameter(OUT MoIMURectify * const pImuParam);
DLL_API_C_DECL int moLocalSetImuRectifyParameter(IN const MoIMURectify *pImuParam);
/**
 * @brief
 * 对视差图离散点过滤
 *
 * @param depth_Frame 视差图数据
 */
DLL_API_C_DECL void moLocalOutlierRemove(IN OUT MoFrame *depth_Frame);

/**
 * @brief
 * 加强对视差图进行深度过滤，清除重复纹理
 *
 * @param pDisp，视差图数据
 */
DLL_API_C_DECL int moLocalEnhanceRemoveDupTexture(OUT MoFrame **ppDispForVSLAM, IN OUT MoFrame *pDisp, IN MoFrame *pRef,   
                 float farPlaneInMM, uint16_t ROIStartX, uint16_t ROIStartY, uint16_t ROIWidth, uint16_t ROIHeight, OUT float *ROIDispFillRate);

#ifdef __cplusplus
}
#endif



#endif
